<?php
class ApiSec extends CModel
{
    const TOKEN_KEY_IN_SESSION = 'WEB_API_TOKEN';
    const TIME_KEY_IN_SESSION = 'WEB_API_TIME_DIFFERENT';
    
    // client time
    public $t;
    // server time
    public $st;
    // client hash value
    public $hash;
    // token used by client
    public $token;
    
    public function rules(){
        return array(
            array('t,st,hash,token','safe'),
        );
    }
    
    public function getNewToken() {
        $token = randomString('all',32);
        Yii::app()->session->add(self::TOKEN_KEY_IN_SESSION, $token);
        return $token;
    }
    
    public function logTimeDifference($result){
        $diff = Yii::app()->session->get(self::TIME_KEY_IN_SESSION, null);
        if (is_null($diff))
            Yii::app()->session->add(self::TIME_KEY_IN_SESSION, $this->t - $this->st);
        else
            $this->validCallTime($result);
    }
    
    /**
    * Validate a Web API request
    * 
    * @param FServiceModel $serviceResult
    */
    public function isValid($serviceResult){
//        $this->token = Yii::app()->session->get(self::TOKEN_KEY_IN_SESSION,'');
        if (empty($this->token) || $this->token !== Yii::app()->session->get(self::TOKEN_KEY_IN_SESSION,null)){
            $serviceResult->fail(9999, Yii::t('Core.WebApi','Invalid token.'));
            return false;
        }
            
        if (!$this->validCallTime($serviceResult)){
            $serviceResult->fail(-10002, Yii::t('Core.WebApi','Network error, please try again.'));
            return false;
        }

        if (!hasParam('Settings::WEB_API_PUBLIC_KEY')){
            $serviceResult->fail(-10000, Yii::t('Core.WebApi','Server does not have PubKey defined.'));
            return false;
        }
            
        $pubKey = Settings::WEB_API_PUBLIC_KEY;
        if (md5($this->token . $pubKey . $this->t) === $this->hash)
            return true;
        else{
            echo $this->hash, ' - ', md5($this->token . $pubKey . $this->t);
            $serviceResult->fail(-10001, Yii::t('Core.WebApi','Unable to validate service consumer.'));
        }
        
        return false;
    }
    
    public function attributeNames(){
        return array(
            't' => 'Service call time',
            'hash' => 'Service hash',
            'token' => 'Service token'
        );
    }
    
    protected function validCallTime(&$serviceResult){
        $diff = Yii::app()->session->get(self::TIME_KEY_IN_SESSION, null);
        if (is_null($diff))
            return false;

        if (abs($diff) > abs($this->t - $this->st)){
            $diff = $this->t - $this->st;
            Yii::app()->session->add(self::TIME_KEY_IN_SESSION, $diff);
        }


        $callTime = $this->t - CPropertyValue::ensureInteger($diff);
        if (abs($callTime - $this->st) <= Settings::WEB_API_TRANSFER_TIME_LIMIT)
        {
            return true;
        }
        else
        {
            $serviceResult->processed('requestReceived',date('m-d-Y H:i:s', $this->st));
            $serviceResult->processed('requestMadeOnClient',date('m-d-Y H:i:s', $this->t));
            $serviceResult->processed('clientServerDiff',$diff);
            $serviceResult->processed('adjustedTime',date('m-d-Y H:i:s', $callTime));            
        }
            
        return false;
    }
}